<?php

namespace App\V3\V3_2_7\Services;

use App\V3\V3_2_7\Models\LogInStorageModel;
use App\V3\V3_2_7\Models\LogOutStorageModel;
use App\V3\V3_2_7\Models\MaterielsTypeModel;
use App\V3\V3_2_7\Models\OperMainAccountModel;
use App\V3\V3_2_7\Models\SerialNumberModel;
use App\V3\V3_2_7\Models\StorageBatchModel;
use App\V3\V3_2_7\Models\StorageManageModel;
use App\V3\V3_2_7\Models\StorageModel;
use App\V3\V3_2_7\Models\StorageShelfLocationModel;
use App\V3\V3_2_7\Models\StorageShelfModel;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

class AllocateService
{
    public static function allocate($data, $time)
    {
        $allocateInfo = json_decode($data['allocate_info'], true);
        $logData = '';
        DB::beginTransaction();
        try {
            $logInStorageInfo = [];
            $logOutStorageInfo = [];
            $serialAllocateInfo = [];
            $storageManageOutData = [];
            $storageManageInData = [];
            $inStorageId = [];
            $outStorageId = [];
            foreach ($allocateInfo as $value) {
                $storageManageInfo = StorageManageModel::select(
                    'a.*',
                    'b.is_use_serial',
                    'b.cost',
                    'b.selling_price'
                )
                    ->from('storage_manage as a')
                    ->leftJoin('materiel_type as b', 'b.id', '=', 'a.type_id')
                    ->where('a.id', $value['id'])
                    ->where('a.main_id', $data['main_id'])
                    ->first();

                if (empty($storageManageInfo) || $storageManageInfo['delete_flag']) {
                    throw new Exception('调拨信息中含有不存在的商品库存，无法调拨');
                }

                /*if($storageManageInfo['virtual_storage_num'] < $value['allocate_num']) {
                    throw new Exception('商品:'.$storageManageInfo['materiel_name'].'当前可用库存数(X'.$storageManageInfo['virtual_storage_num'].')不足'.'调拨数量X'.$value['allocate_num']);
                }*/
                if (!OperMainAccountModel::query()
                    ->where([
                        'main_id' => $data['main_id'],
                        'delete_flag' => 0
                    ])->exists()) {
                    if ($storageManageInfo['in_storage_num'] < $value['allocate_num']) {
                        throw new Exception('商品:' . $storageManageInfo['materiel_name'] . '当前实际可用库存数(X' . $storageManageInfo['virtual_storage_num'] . ')不足' . '调拨数量X' . $value['allocate_num']);
                    }
                }

                if (empty($value['storage_id'])) {
                    throw new Exception('请为商品:' . $storageManageInfo['materiel_name'] . '选择调入仓库');
                }

                $storageInfo = StorageModel::where([
                    'id' => $value['storage_id'],
                    'main_id' => $data['main_id']
                ])->first();

                if (empty($storageInfo) || $storageInfo['delete_flag']) {
                    throw new Exception('商品:' . $storageManageInfo['materiel_name'] . '调入选定的仓库不存在或已被删除，无法完成调拨，请重试');
                }

                //调入库存货架信息
                if (empty($value['location_id'])) {
                    //获取货架
                    $shelfInfo = StorageShelfModel::where([
                        'storage_id' => $value['storage_id'],
                        'shelf_type' => 1
                    ])->first();

                    $shelfId = $shelfInfo['id'];
                    //获取库位
                    $locationInfo = StorageShelfLocationModel::where([
                        'shelf_id' => $shelfId,
                        'location_type' => 1
                    ])
                        ->first();

                    $locationId = $locationInfo['id'];
                    if (!empty($locationId)) {

                        if ($storageManageInfo['location_id'] === $locationId) {
                            throw new \RuntimeException('商品:' . $storageManageInfo['materiel_name'] . '禁止同库位调拨');
                        }
                    }
                } else {
                    $shelfId = $value['shelf_id'];
                    $locationId = $value['location_id'];
                    if (!empty($value['location_id'])) {
                        if ($storageManageInfo['location_id'] === $value['location_id']) {
                            throw new \RuntimeException('商品:' . $storageManageInfo['materiel_name'] . '禁止同库位调拨');
                        }
                    }
                }

                //调出货架信息
                if (empty($value['out_location_id'])) {
                    //获取货架
                    $shelfInfo = StorageShelfModel::where([
                        'storage_id' => $storageManageInfo['storage_id'],
                        'shelf_type' => 1
                    ])->first();

                    $outShelfId = $shelfInfo['id'];

                    //获取库位
                    $locationInfo = StorageShelfLocationModel::where([
                        'shelf_id' => $outShelfId,
                        'location_type' => 1
                    ])
                        ->first();

                    $outLocationId = $locationInfo['id'];
                } else {
                    $outShelfId = $value['out_shelf_id'];
                    $outLocationId = $value['out_location_id'];
                }

                //检查调入仓库库存信息是否存在
                $checkInStorageInfo = StorageManageModel::where([
                    'type_id' => $storageManageInfo['type_id'],
                    'storage_id' => $value['storage_id'],
                    'main_id' => $data['main_id'],
                    'delete_flag' => 0,
                    'shelf_id' => $shelfId,
                    'location_id' => $locationId,
                ])->first();

                if (empty($checkInStorageInfo)) {
                    $storageManageId = StorageManageModel::insertGetId([
                        'materiel_class_id' => $storageManageInfo['materiel_class_id'],
                        'materiel_class_name' => $storageManageInfo['materiel_class_name'],
                        'materiel_class_no' => $storageManageInfo['materiel_class_no'],
                        'type_id' => $storageManageInfo['type_id'],
                        'materiel_name' => $storageManageInfo['materiel_name'],
                        'type_name' => $storageManageInfo['type_name'],
                        'materiel_no' => $storageManageInfo['materiel_no'],
                        'materiel_mean_cost' => $storageManageInfo['cost'],
                        'storage_id' => $storageInfo['id'],
                        'storage_name' => $storageInfo['storage_name'],
                        'storage_address' => $storageInfo['storage_address'],
                        'in_storage_num' => $value['allocate_num'],
                        //'virtual_storage_num' => $value['allocate_num'],
                        'main_id' => $data['main_id'],
                        'materiel_original' => 1,
                        'in_storage_time' => $time,
                        'created_at' => $time,
                        'shelf_id' => $shelfId,
                        'location_id' => $locationId,
                    ]);

                    $inStorageId[] = $storageManageId;

                    $currStorageNum = 0;
                } else {
                    $storageManageId = $checkInStorageInfo['id'];
                    $currStorageNum = $checkInStorageInfo['in_storage_num'];

                    $storageManageInData[] = [
                        'id' => $storageManageId,
                        'in_storage_num' => $checkInStorageInfo['in_storage_num'] + $value['allocate_num'],
                        //'virtual_storage_num' => $checkInStorageInfo['virtual_storage_num'] + $value['allocate_num'],
                    ];

                    $inStorageId[] = $storageManageId;
                }

                $serialInfo = '';
                if ($storageManageInfo['is_use_serial']) {
                    if (empty($value['serial_info'])) {
                        throw new Exception('商品:' . $storageManageInfo['materiel_name'] . '已开启序列号，请选择序列号后重试');
                    } else {
                        $serialNumberInfo = array_filter(explode(',', $value['serial_info']), function ($v) {
                            return $v !== '';
                        });
                        if (count($serialNumberInfo) != $value['allocate_num']) {
                            throw new Exception('商品:' . $storageManageInfo['materiel_name'] . '调拨数量与调拨所选择的序列号数量不符,请检查后重试');
                        }

                        foreach ($serialNumberInfo as $serialValue) {
                            $serialDetailInfo = SerialNumberModel::where([
                                'id' => $serialValue,
                                'goods_id' => $storageManageInfo['type_id'],
                                'storage_manage_id' => $storageManageInfo['id'],
                                'delete_flag' => 0
                            ])->first();

                            if (empty($serialDetailInfo)) {
                                throw new Exception('商品:' . $storageManageInfo['materiel_name'] . '存在无效序列号');
                            }

                            if (!$serialDetailInfo['status']) {
                                throw new Exception('商品:' . $storageManageInfo['materiel_name'] . '的序列号:' . $serialDetailInfo['serial_no'] . '已被使用');
                            }

                            $serialInfo .= $serialDetailInfo['serial_no'] . ',';

                            $serialAllocateInfo[] = [
                                'storage_manage_id' => $storageManageId,
                                'id' => $serialValue
                            ];
                        }
                    }
                }

                $storageManageOutData[] = [
                    'id' => $value['id'],
                    'in_storage_num' => $storageManageInfo['in_storage_num'] - $value['allocate_num'],
                    //'virtual_storage_num' => $storageManageInfo['virtual_storage_num'] - $value['allocate_num'],
                ];

                $outStorageId[] = $value['id'];

                $logInStorageInfo[] = [
                    'type' => 1,
                    'storage_id' => $storageInfo['id'],
                    'storage_name' => $storageInfo['storage_name'],
                    'storage_address' => $storageInfo['storage_address'],
                    'last_storage_manage_id' => $value['id'],
                    'curr_storage_manage_id' => $storageManageId,
                    'last_storage_id' => $storageManageInfo['storage_id'],
                    'last_storage_name' => $storageManageInfo['storage_name'],
                    'last_storage_address' => $storageManageInfo['storage_address'],
                    'materiel_class_id' => $storageManageInfo['materiel_class_id'],
                    'materiel_class_name' => $storageManageInfo['materiel_class_name'],
                    'materiel_class_no' => $storageManageInfo['materiel_class_no'],
                    'materiel_type_id' => $storageManageInfo['type_id'],
                    'materiel_name' => $storageManageInfo['materiel_name'],
                    'type_name' => $storageManageInfo['type_name'],
                    'materiel_no' => $storageManageInfo['materiel_no'],
                    'operate_num' => $value['allocate_num'],
                    'allocate_no' => $data['allocate_no'],
                    'last_storage_num' => $currStorageNum,
                    'next_storage_num' => $currStorageNum + $value['allocate_num'],
                    'materiel_mean_cost' => $storageManageInfo['cost'],
                    'serial_number' => empty($serialInfo) ? '' : substr($serialInfo, 0, -1),
                    'batch_id' => 0,
                    'before_allocate_batch_id' => 0,
                    'all_id_type' => 0,
                    'all_id' => 0,
                    'user_id' => $data['user_id'],
                    'main_id' => $data['main_id'],
                    'in_storage_time' => $data['allocate_time'],
                    'created_at' => $time,
                    'shelf_id' => $shelfId,
                    'location_id' => $locationId,
                    'label_id' => $data['label_id'],
                    'label_name' => $data['label_name'],
                    'remark' => empty($value['remark']) ? '' : $value['remark'],
                    'general_remarks' => $data['general_remarks'] ?? ''
                ];

                $logOutStorageInfo[] = [
                    'type' => 1,
                    'storage_batch_id' => 0,
                    'allocate_no' => $data['allocate_no'],
                    'before_allocate_batch_id' => 0,
                    'storage_id' => $storageManageInfo['storage_id'],
                    'storage_name' => $storageManageInfo['storage_name'],
                    'storage_address' => $storageManageInfo['storage_address'],
                    'next_storage_id' => $storageInfo['id'],
                    'next_storage_name' => $storageInfo['storage_name'],
                    'next_storage_address' => $storageInfo['storage_address'],
                    'curr_storage_manage_id' => $storageManageInfo['id'],
                    'next_storage_manage_id' => $storageManageId,
                    'materiel_class_id' => $storageManageInfo['materiel_class_id'],
                    'materiel_class_name' => $storageManageInfo['materiel_class_name'],
                    'materiel_class_no' => $storageManageInfo['materiel_class_no'],
                    'materiel_type_id' => $storageManageInfo['type_id'],
                    'materiel_name' => $storageManageInfo['materiel_name'],
                    'type_name' => $storageManageInfo['type_name'],
                    'materiel_no' => $storageManageInfo['materiel_no'],
                    'operate_num' => $value['allocate_num'],
                    'last_storage_num' => $storageManageInfo['in_storage_num'],
                    'next_storage_num' => $storageManageInfo['in_storage_num'] - $value['allocate_num'],
                    'serial_number' => $serialInfo,
                    'sell_price' => $storageManageInfo['selling_price'],
                    'materiel_mean_cost' => $storageManageInfo['cost'],
                    'user_id' => $data['user_id'],
                    'main_id' => $data['main_id'],
                    'out_storage_time' => $data['allocate_time'],
                    'fact_out_time' => $time,
                    'created_at' => $time,
                    'shelf_id' => $outShelfId,
                    'location_id' => $outLocationId,
                    'label_id' => $data['label_id'],
                    'label_name' => $data['label_name'],
                    'remark' => empty($value['remark']) ? '' : $value['remark'],
                    'general_remarks' => $data['general_remarks'] ?? ''
                ];

                $logData .= '商品名称：' . $storageManageInfo['materiel_name'] . '（' . $storageManageInfo['materiel_no'] . '）' .
                    '调拨数量：' . $value['allocate_num'] . ' 仓库名：' . $storageInfo['storage_name'] . ',';
            }

            if (!empty($logInStorageInfo)) {
                LogInStorageModel::insert($logInStorageInfo);
            }

            if (!empty($logOutStorageInfo)) {
                LogOutStorageModel::insert($logOutStorageInfo);
            }

            if (!empty($serialAllocateInfo)) {
                batch()->update(new SerialNumberModel, $serialAllocateInfo, 'id');
            }

            if (!empty($storageManageInData)) {
                batch()->update(new StorageManageModel, $storageManageInData, 'id');
            }

            if (!empty($storageManageOutData)) {
                batch()->update(new StorageManageModel, $storageManageOutData, 'id');
            }

            //开启预警
            StorageManageModel::where('main_id', $data['main_id'])
                ->whereRaw('in_storage_num < alert_num')
                ->update(['sort_flag' => 1]);

            //结束预警
            StorageManageModel::where('main_id', $data['main_id'])
                ->whereRaw('in_storage_num > alert_num')
                ->update(['sort_flag' => 0]);

//            if(!empty($inStorageId)) {
//                $storageInInfo = StorageManageModel::whereIn('id', $inStorageId)
//                    ->whereRaw('in_storage_num > alert_num')
//                    ->get()->toArray();
//
//                $storageInIdArr = [];
//                foreach($storageInInfo as $storageInValue) {
//                    $storageInIdArr[] = [
//                        'id' => $storageInValue['id'],
//                        'sort_flag' => 0
//                    ];
//                }
//
//                batch()->update(new StorageManageModel, $storageInIdArr, 'id');
//            }
//
//            if(!empty($outStorageId)) {
//                $storageInInfo = StorageManageModel::whereIn('id', $outStorageId)
//                    ->whereRaw('in_storage_num < alert_num')
//                    ->get()->toArray();
//
//                $storageOutIdArr = [];
//                foreach($storageInInfo as $storageInValue) {
//                    $storageOutIdArr[] = [
//                        'id' => $storageInValue['id'],
//                        'sort_flag' => 0
//                    ];
//                }
//                batch()->update(new StorageManageModel, $storageOutIdArr, 'id');
//            }

            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => $logData];
        } catch (\Exception $e) {
            DB::rollBack();
            Log::debug('调拨异常:' . var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    static private function serialAllocate($allocateInInfo, $data, $storageInfo, $storageManageInfo, $materielTypeInfo, $allocateNum, $serialInfo)
    {
        if (empty($allocateInInfo)) {
            $storageManageId = self::createNewStorageInfo($data, $materielTypeInfo, $storageInfo, $allocateNum);

            StorageManageModel::where('id', $storageManageInfo['id'])->update([
                'in_storage_num' => DB::raw('in_storage_num -' . $allocateNum),
                'virtual_storage_num' => DB::raw('virtual_storage_num -' . $allocateNum),
            ]);

            $currStorageNum = 0;
            $uselessAllocate = 0;
        } else {
            $storageManageId = $allocateInInfo['id'];

            if ($serialInfo['storage_manage_id'] != $allocateInInfo['id']) {
                StorageManageModel::where('id', $allocateInInfo['id'])
                    ->update([
                        'in_storage_num' => DB::raw('in_storage_num +' . $allocateNum),
                        'virtual_storage_num' => DB::raw('virtual_storage_num +' . $allocateNum),
                        'delete_flag' => 0
                    ]);

                StorageManageModel::where('id', $storageManageInfo['id'])->update([
                    'in_storage_num' => DB::raw('in_storage_num -' . $allocateNum),
                    'virtual_storage_num' => DB::raw('virtual_storage_num -' . $allocateNum),
                ]);

                $currStorageNum = $allocateInInfo['in_storage_num'];
                $uselessAllocate = 0;
            } else {
                $uselessAllocate = 1;
            }
        }

        $batchNo = self::generatorBatchNo($data);
        $batchId = self::createdBatch($batchNo, $storageManageId, $materielTypeInfo, $data, $allocateNum);

        if (!$uselessAllocate) {
            SerialNumberModel::where('id', $serialInfo['id'])
                ->update([
                    'storage_manage_id' => $storageManageId
                ]);

            $logInId = self::generatorAllocateInLog($data, $storageManageId, $storageManageInfo, $storageInfo, $currStorageNum, $allocateNum, $batchId, $serialInfo['serial_no']);
            $logOutId = self::generatorAllocateOutLog($data, $storageManageInfo, $storageInfo, $storageManageId, $materielTypeInfo, $allocateNum, $serialInfo['serial_no'], $batchId);

            LogInStorageModel::where('id', $logInId)
                ->update([
                    'log_out_id' => $logOutId
                ]);

            LogOutStorageModel::where('id', $logOutId)
                ->update([
                    'log_in_id' => $logInId
                ]);
        }

        return true;
    }

    //批次号调拨
    static private function batchAllocate($allocateInInfo, $data, $storageInfo, $storageManageInfo, $materielTypeInfo, $allocateNum, $batchInfo)
    {
        if (empty($allocateInInfo)) {
            $storageManageId = self::createNewStorageInfo($data, $materielTypeInfo, $storageInfo, $allocateNum);
            $currStorageNum = 0;

            $batchId = StorageBatchModel::insertGetId([
                'batch_no' => $batchInfo['batch_no'],
                'storage_manage_id' => $storageManageId,
                'batch_num' => $allocateNum,
                'batch_left_num' => $allocateNum,
                'batch_cost' => $storageManageInfo['materiel_mean_cost'],
                'main_id' => $data['main_id'],
                'created_at' => time()
            ]);
        } else {
            StorageManageModel::where('id', $allocateInInfo['id'])
                ->update([
                    'in_storage_num' => DB::raw('in_storage_num +' . $allocateNum),
                    'virtual_storage_num' => DB::raw('virtual_storage_num +' . $allocateNum),
                    'delete_flag' => 0
                ]);

            $storageManageId = $allocateInInfo['id'];
            $currStorageNum = $allocateInInfo['in_storage_num'];

            $checkBatchInfo = StorageBatchModel::where([
                'storage_manage_id' => $allocateInInfo['id'],
                'id' => $batchInfo['id'],
                'delete_flag' => 0
            ])->first();

            if (empty($checkBatchInfo)) {
                $batchId = StorageBatchModel::insertGetId([
                    'batch_no' => $batchInfo['batch_no'],
                    'storage_manage_id' => $storageManageId,
                    'batch_num' => $allocateNum,
                    'batch_left_num' => $allocateNum,
                    'batch_cost' => $allocateInInfo['materiel_mean_cost'],
                    'main_id' => $data['main_id'],
                    'created_at' => time()
                ]);
            } else {
                StorageBatchModel::where('id', $checkBatchInfo['id'])
                    ->update([
                        'batch_num' => DB::raw('batch_num +' . $allocateNum),
                        'batch_left_num' => DB::raw('batch_left_num +' . $allocateNum),
                        'delete_flag' => 0
                    ]);

                $batchId = $checkBatchInfo['id'];
            }
        }

        StorageManageModel::where('id', $storageManageInfo['id'])->update([
            'in_storage_num' => DB::raw('in_storage_num -' . $allocateNum),
            'virtual_storage_num' => DB::raw('virtual_storage_num -' . $allocateNum),
        ]);

        StorageBatchModel::where('id', $batchInfo['id'])
            ->update([
                'batch_num' => DB::raw('batch_num -' . $allocateNum),
                'batch_left_num' => DB::raw('batch_left_num -' . $allocateNum),
                'delete_flag' => 0
            ]);

        $logInId = self::generatorAllocateInLog($data, $storageManageId, $storageManageInfo, $storageInfo, $currStorageNum, $allocateNum, $batchId, '', $batchInfo['id']);
        $logOutId = self::generatorAllocateOutLog($data, $storageManageInfo, $storageInfo, $storageManageId, $materielTypeInfo, $allocateNum, '', $batchId, $batchInfo['id']);

        LogInStorageModel::where('id', $logInId)
            ->update([
                'log_out_id' => $logOutId
            ]);

        LogOutStorageModel::where('id', $logOutId)
            ->update([
                'log_in_id' => $logInId
            ]);

        return true;
    }

    /**
     *
     * @param $allocateInInfo 目标库存信息
     * @param $data 表单获取的数据
     * @param $storageInfo 调出仓库信息
     * @param $storageManageInfo 调出库存信息
     * @param $materielTypeInfo 调出商品信息
     * 2022/9/27 15:19
     * Author: Sun Wu
     * @return bool
     */
    static private function normalAllocate($allocateInInfo, $data, $storageInfo, $storageManageInfo, $materielTypeInfo, $allocateNum)
    {
        if (empty($allocateInInfo)) {
            $storageManageId = self::createNewStorageInfo($data, $materielTypeInfo, $storageInfo, $allocateNum);
            $currStorageNum = 0;
        } else {
            StorageManageModel::where('id', $allocateInInfo['id'])
                ->update([
                    'in_storage_num' => DB::raw('in_storage_num +' . $allocateNum),
                    'virtual_storage_num' => DB::raw('virtual_storage_num +' . $allocateNum),
                    'delete_flag' => 0
                ]);

            $storageManageId = $allocateInInfo['id'];
            $currStorageNum = $allocateInInfo['in_storage_num'];
        }

        StorageManageModel::where('id', $storageManageInfo['id'])->update([
            'in_storage_num' => DB::raw('in_storage_num -' . $allocateNum),
            'virtual_storage_num' => DB::raw('virtual_storage_num -' . $allocateNum),
        ]);

        $batchNo = self::generatorBatchNo($data);
        $batchId = self::createdBatch($batchNo, $storageManageId, $materielTypeInfo, $data, $allocateNum);

        $logInId = self::generatorAllocateInLog($data, $storageManageId, $storageManageInfo, $storageInfo, $currStorageNum, $allocateNum, $batchId);
        $logOutId = self::generatorAllocateOutLog($data, $storageManageInfo, $storageInfo, $storageManageId, $materielTypeInfo, $allocateNum);

        LogInStorageModel::where('id', $logInId)
            ->update([
                'log_out_id' => $logOutId
            ]);

        LogOutStorageModel::where('id', $logOutId)
            ->update([
                'log_in_id' => $logInId
            ]);

        return true;
    }

    static public function generatorAllocateOutLog($data, $storageManageInfo, $storageInfo, $nextStorageManageId, $materielTypeInfo, $allocateNum, $serialInfo = '', $batchId = '', $beforBatchId = 0)
    {
        return LogOutStorageModel::insertGetId([
            'type' => 1,
            'storage_batch_id' => $batchId,
            'allocate_no' => $data['allocate_no'],
            'before_allocate_batch_id' => $beforBatchId,
            'storage_id' => $storageManageInfo['storage_id'],
            'storage_name' => $storageManageInfo['storage_name'],
            'storage_address' => $storageManageInfo['storage_address'],
            'next_storage_id' => $storageInfo['id'],
            'next_storage_name' => $storageInfo['storage_name'],
            'next_storage_address' => $storageInfo['storage_address'],
            'curr_storage_manage_id' => $storageManageInfo['id'],
            'next_storage_manage_id' => $nextStorageManageId,
            'materiel_class_id' => $materielTypeInfo['materiel_class_id'],
            'materiel_class_name' => $materielTypeInfo['class_name'],
            'materiel_class_no' => $materielTypeInfo['class_no'],
            'materiel_type_id' => $materielTypeInfo['id'],
            'materiel_name' => $materielTypeInfo['materiel_name'],
            'type_name' => $materielTypeInfo['type_name'],
            'materiel_no' => $materielTypeInfo['materiel_no'],
            'operate_num' => $allocateNum,
            'last_storage_num' => $storageManageInfo['in_storage_num'],
            'next_storage_num' => $storageManageInfo['in_storage_num'] - $allocateNum,
            'serial_number' => $serialInfo,
            'sell_price' => $materielTypeInfo['selling_price'],
            'materiel_mean_cost' => $materielTypeInfo['cost'],
            'user_id' => $data['user_id'],
            'main_id' => $data['main_id'],
            'remark' => empty($data['remark']) ? '' : $data['remark'],
            'out_storage_time' => time(),
            'fact_out_time' => time(),
            'created_at' => time(),
            'shelf_id' => $data['shelf_id'],
            'location_id' => $data['location_id'],
            'label_name' => !empty($data['label_name']) ? $data['label_name'] : '',

        ]);
    }

    static public function generatorAllocateInLog($data, $storageManageId, $storageManageInfo, $storageInfo, $currStorageNum, $allocateNum, $batchId, $serialInfo = '', $beforeBatchId = '')
    {
        return LogInStorageModel::insertGetId([
            'type' => 1,
            'storage_id' => $storageInfo['id'],
            'storage_name' => $storageInfo['storage_name'],
            'storage_address' => $storageInfo['storage_address'],
            'last_storage_manage_id' => $storageManageInfo['id'],
            'curr_storage_manage_id' => $storageManageId,
            'last_storage_id' => $storageManageInfo['storage_id'],
            'last_storage_name' => $storageManageInfo['storage_name'],
            'last_storage_address' => $storageManageInfo['storage_address'],
            'materiel_class_id' => $storageManageInfo['materiel_class_id'],
            'materiel_class_name' => $storageManageInfo['class_name'],
            'materiel_class_no' => $storageManageInfo['class_no'],
            'materiel_type_id' => $storageManageInfo['type_id'],
            'materiel_name' => $storageManageInfo['materiel_name'],
            'type_name' => $storageManageInfo['type_name'],
            'materiel_no' => $storageManageInfo['materiel_no'],
            'operate_num' => $allocateNum,
            'allocate_no' => $data['allocate_no'],
            'last_storage_num' => $currStorageNum,
            'next_storage_num' => $currStorageNum + $allocateNum,
            'materiel_mean_cost' => $storageManageInfo['cost'],
            'serial_number' => $serialInfo,
            'remark' => empty($data['remark']) ? '' : $data['remark'],
            'batch_id' => $batchId,
            'before_allocate_batch_id' => $beforeBatchId,
            'all_id_type' => 0,
            'all_id' => 0,
            'user_id' => $data['user_id'],
            'main_id' => $data['main_id'],
            'in_storage_time' => time(),
            'created_at' => time(),
            'shelf_id' => $data['shelf_id'],
            'location_id' => $data['location_id'],
            'label_name' => !empty($data['label_name']) ? $data['label_name'] : '',

        ]);
    }

    static public function getNewStorageManageInfo($storageManageId)
    {
        return StorageManageModel::select(
            'a.id',
            'type_id',
            'b.materiel_name',
            'b.type_name',
            'storage_id',
            'c.storage_name',
            'c.storage_address',
            'a.materiel_class_id',
            'd.class_name',
            'd.class_no',
            'b.cost',
            'a.in_storage_num',
            'a.virtual_storage_num',
            'location_id',
            'shelf_id'
        )
            ->from('storage_manage as a')
            ->leftJoin('materiel_type as b', 'b.id', '=', 'a.type_id')
            ->leftJoin('storage as c', 'c.id', '=', 'a.storage_id')
            ->leftJoin('materiel_class as d', 'd.id', '=', 'b.materiel_class_id')
            ->where([
                'a.id' => $storageManageId,
                'a.delete_flag' => 0
            ])->first();
    }


    //获取库存信息
    static public function getStorageManageInfo($storageManageId)
    {
        return StorageManageModel::select(
            'a.id',
            'type_id',
            'a.materiel_name',
            'a.type_name',
            'storage_id',
            'a.storage_name',
            'a.storage_address',
            'a.materiel_class_id',
            'd.class_name',
            'd.class_no',
            'a.materiel_mean_cost',
            'a.in_storage_num',
            'location_id',
            'shelf_id'
        )
            ->from('storage_manage as a')
            ->leftJoin('materiel_type as b', 'b.id', '=', 'a.type_id')
            ->leftJoin('storage as c', 'c.id', '=', 'a.storage_id')
            ->leftJoin('materiel_class as d', 'd.id', '=', 'b.materiel_class_id')
            ->where([
                'a.id' => $storageManageId,
                'a.delete_flag' => 0
            ])->first();
    }

    //生成新的库存信息
    static public function createNewStorageInfo($data, $materielTypeInfo, $storageInfo, $allocateNum)
    {
        return StorageManageModel::insertGetId([
            'materiel_class_id' => $materielTypeInfo['materiel_class_id'],
            'materiel_class_name' => $materielTypeInfo['class_name'],
            'materiel_class_no' => $materielTypeInfo['class_no'],
            'type_id' => $materielTypeInfo['id'],
            'materiel_name' => $materielTypeInfo['materiel_name'],
            'type_name' => $materielTypeInfo['type_name'],
            'materiel_no' => $materielTypeInfo['materiel_no'],
            'materiel_mean_cost' => $materielTypeInfo['cost'],
            'storage_id' => $storageInfo['id'],
            'storage_name' => $storageInfo['storage_name'],
            'storage_address' => $storageInfo['storage_address'],
            'in_storage_num' => $allocateNum,
            'virtual_storage_num' => $allocateNum,
            'main_id' => $data['main_id'],
            'materiel_original' => 1,
            'in_storage_time' => time(),
            'created_at' => time(),
            'shelf_id' => $data['shelf_id'],
            'location_id' => $data['location_id'],
        ]);
    }

    //create new batch no in storage
    static public function createdBatch($batchNo, $storageManageId, $materielTypeInfo, $data, $allocateNum)
    {
        return StorageBatchModel::insertGetId([
            'batch_no' => $batchNo,
            'storage_manage_id' => $storageManageId,
            'batch_num' => $allocateNum,
            'batch_left_num' => $allocateNum,
            'batch_cost' => $materielTypeInfo['cost'],
            'main_id' => $data['main_id'],
            'created_at' => time()
        ]);
    }

    //校验调入库存信息是否已存在
    static public function checkExist($data, $materielTypeInfo)
    {
        return StorageManageModel::where([
            'type_id' => $materielTypeInfo['id'],
            'location_id' => $data['location_id'],
        ])
            ->first();
    }

    static public function generatorBatchNo($data)
    {
        $batchNo = $data['batch_title'] . date('YmdHis', time()) . mt_rand(1000, 9999) . '0';
        $checkBatchNo = StorageBatchModel::where('main_id', $data['main_id'])
            ->where('batch_no', $batchNo)->first();

        do {
            $batchNo = $data['batch_title'] . date('YmdHis', time()) . mt_rand(1000, 9999) . '0';
        } while (!empty($checkBatchNo));

        return $batchNo;
    }
}
